package com.a918.controller;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.a918.dto.TableResponse;
import com.a918.entity.User;
import com.a918.entity.Userlog;
import com.a918.service.UserService;
import com.a918.util.IPGet;
import com.a918.util.RequestUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;
import java.util.Random;

@Controller
public class UserController {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UserController.class);
    private UserService userService;

    @Value("${url.login}")
    private String LOGIN_URL;

    @Value("${url.sso}")
    private String SSO_URL;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @RequestMapping("index")
    public String hello(){
        return "index1";
    }

    @RequestMapping(value={"/","/xlpj"})
    public String platform_index(HttpServletRequest request, HttpSession session) {
        // 解决共享平台单点登录
        String source = request.getParameter("source");
        if (source != null && source.equals("platform")) {
            // TODO: 根据token获取用户名，设置username为共享平台用户
            String tokenPlatform = request.getParameter("token");
            if (tokenPlatform == null) {
                return "redirect:" + LOGIN_URL;
            }
            String res = RequestUtil.sendGet(SSO_URL, tokenPlatform, "UTF-8");
            JSONObject jsonObject = JSONUtil.parseObj(res);
            int code = (int) jsonObject.get("code");
            if (code != 200) {
                // 请求失败！
                return "redirect:" + LOGIN_URL;
            }

            // 模拟登录
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken("admin", "kjwl!123");
            try {
                subject.login(token);
                User user = (User) subject.getPrincipal();
                session.setAttribute("username", user.getUsername());
                session.setAttribute("id", user.getId());
                userService.insertlog("共享平台登录成功","login",user.getUsername(),IPGet.getIp(request));
            } catch (Throwable e) {
                e.printStackTrace();
            }
            return "index";
        }
        return "redirect:/index";
    }


    @GetMapping("/login")
    public String login() {
//        log.error("Something else is wrong here---login");
        //如果已经认证通过，直接跳转到首页
        if (SecurityUtils.getSubject().isAuthenticated()) {
            return "redirect:/index";
        }

        return "user/login";
    }

    @PostMapping("/login")
    public Object login(String username, String password, String code, Model model, HttpSession session,HttpServletRequest request) {

        String sessionCaptcha  = (String)SecurityUtils.getSubject().getSession().getAttribute("CODE");

        if(!sessionCaptcha.equals(code.toUpperCase())){
            model.addAttribute("error","验证码错误！");
            return "user/login";
        }
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        String error = null;
        try {
            //shiro帮我们匹配密码什么的，我们只需要把东西传给它，它会根据我们在UserRealm里认证方法设置的来验证
            subject.login(token);
            User user = (User) subject.getPrincipal();
            session.setAttribute("username", user.getUsername());
            session.setAttribute("id", user.getId());
            userService.insertlog("登录成功","login",user.getUsername(),IPGet.getIp(request));
            return "redirect:/index";
        } catch (UnknownAccountException e) {
            //账号不存在和下面密码错误一般都合并为一个账号或密码错误，这样可以增加暴力破解难度
            error = "账号不存在！";
        } catch (DisabledAccountException e) {
            error ="账号未启用！";
        } catch (IncorrectCredentialsException e) {
            error ="密码错误！";
        } catch (Throwable e) {
            e.printStackTrace();
            error ="未知错误！";
        }
        if(null != error){
            model.addAttribute("error",error);
            return "user/login";
        }

        return "redirect:/index";
    }

    //系统日志
    @GetMapping("/log")
    public String log(HttpServletRequest request) {
        userService.insertlog("日志管理","log",(String) request.getSession().getAttribute("username"),IPGet.getIp(request));
        return "user/userlog";
    }


    @PostMapping("/loglist")
    @ResponseBody
    public Object loglist(int page, int limit,@RequestParam Map<String, String> paramMap){
        PageHelper.startPage(page, limit);
        PageInfo<Userlog> pageInfo  = new PageInfo<Userlog>(userService.getLogList(paramMap));
        return new TableResponse(0,"查询成功", pageInfo.getList(),pageInfo.getTotal());
    }


    //退出
    @RequestMapping("/logout")
    public String logout(HttpServletRequest request) {
        userService.insertlog("登出","logout",(String) request.getSession().getAttribute("username"),IPGet.getIp(request));
        SecurityUtils.getSubject().logout();
        return "user/login";
    }

    //验证用户名是否重复
    @PostMapping("/checkUsername")
    @ResponseBody
    public String checkUsername(HttpServletRequest request){
        String username = request.getParameter("username");
        if (userService.getUserByUsername(username)!=null){
            return "duplicate";
        }
        return "success";
    }

    //后门加用户
    @RequestMapping("/adduser_houmen")
    public String adduser_houmen(HttpServletRequest request){
        String method = request.getMethod();
        if(!"POST".equalsIgnoreCase(method)){
            return "user/adduser_houmen";
        }
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setCreatetime(new Date());
        userService.insertUser(user);
        return "redirect:login";
    }

    @GetMapping("/modifypwd")
    public String modifypasswd(Model model,HttpServletRequest request) {
        userService.insertlog("","modifypwd",(String) request.getSession().getAttribute("username"),IPGet.getIp(request));
        model.addAttribute("text","111111");
        return "user/modifypwd";
    }

    @PostMapping("/modifypwd")
    @ResponseBody
    public String modifypasswd_submit(HttpServletRequest request) {
        User user = userService.getUserByUsername((String) request.getSession().getAttribute("username"));
        String oldpasswd = request.getParameter("oldpasswd");
        String newpasswd = request.getParameter("newpasswd");
        if(!userService.validatePasswd(user,oldpasswd)){
            return "oldPasswdError";
        };
        user.setPassword(newpasswd);
        userService.updateUser(user);
        return "success";
    }

    //登录验证码
    @GetMapping("/createCode")
    @ResponseBody
    public void createCode(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        BufferedImage bi = new BufferedImage(90, 40, BufferedImage.TYPE_INT_RGB);
        Graphics g = bi.getGraphics();
        //RGB色彩
        Color c = new Color(242, 248, 255);
        // 框中的背景色
        g.setColor(c);
        // 颜色填充像素
        g.fillRect(0, 0, 90, 40);

        // 定义验证码字符数组
        char[] ch = "ABCDEFGHJKMNPQRSTUVWXYZ23456798".toCharArray();
        Random r = new Random();
        int len = ch.length;
        int index;
        StringBuffer sb = new StringBuffer();
        // 取出四个数字
        for (int i = 0; i < 4; i++) {
            // 循环四次随机取长度定义为索引
            index = r.nextInt(len);
            g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt(255)));
            Font font = new Font("Times New Roman", Font.ITALIC, 18);
            g.setFont(font);
            g.drawString(ch[index] + "", (i * 18) + 10, 30);
            sb.append(ch[index]);
        }

        //放入Session中
        request.getSession().setAttribute("CODE", sb.toString());
        try {
            ImageIO.write(bi, "JPG", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/printcheckfile")
    public String printcheckfile(HttpServletRequest request,Model model) {
        User user = userService.getUserByUsername((String) request.getSession().getAttribute("username"));
        model.addAttribute("user",user);
        return "user/printcheckfile";
    }

}
